package com.grant.code.controller;

import javafx.application.Platform;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.fxml.FXML;
import javafx.scene.SnapshotParameters;
import javafx.scene.control.Slider;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.PixelReader;
import javafx.scene.image.PixelWriter;
import javafx.scene.image.WritableImage;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;

/**
 * 头像裁剪器控制器 - 负责用户头像的裁剪和预览功能
 */
public class AvatarCropperController {

    @FXML private StackPane cropperContainer;
    @FXML private ImageView sourceImageView;
    @FXML private ImageView previewImageView;
    @FXML private Slider zoomSlider;
    @FXML private Circle cropCircle;
    @FXML private Circle previewBorder;
    
    private Image originalImage;
    private double startDragX;
    private double startDragY;
    private double imageOffsetX = 0;
    private double imageOffsetY = 0;
    
    // 缩放设置
    private final double MIN_SCALE = 0.5;
    private final double MAX_SCALE = 3.0;
    private final double SCALE_DELTA = 0.05; // 鼠标滚轮缩放步长
    
    // 当前缩放比例
    private final DoubleProperty currentScale = new SimpleDoubleProperty(1.0);
    
    // 临时存储裁剪后的图像
    private File tempCroppedFile;
    
    /**
     * 初始化裁剪器
     */
    @FXML
    private void initialize() {
        // 初始化拖动事件
        sourceImageView.setOnMousePressed(this::handleMousePressed);
        sourceImageView.setOnMouseDragged(this::handleMouseDragged);
        
        // 初始化鼠标滚轮缩放
        cropperContainer.setOnScroll(this::handleScroll);
        
        // 配置缩放滑块
        zoomSlider.setMin(MIN_SCALE);
        zoomSlider.setMax(MAX_SCALE);
        zoomSlider.setValue(1.0);
        zoomSlider.setBlockIncrement(0.05);
        zoomSlider.setMajorTickUnit(0.5);
        zoomSlider.setMinorTickCount(4);
        
        // 绑定缩放滑块
        zoomSlider.valueProperty().bindBidirectional(currentScale);
        
        // 监听缩放变化，更新图像大小
        currentScale.addListener((observable, oldValue, newValue) -> {
            updateImageScale();
            updatePreview();
        });
        
        // 确保裁剪容器不会被溢出
        cropperContainer.setClip(new javafx.scene.shape.Rectangle(
            cropperContainer.getPrefWidth(), 
            cropperContainer.getPrefHeight()
        ));
        
        // 初始化裁剪区域限制
        cropperContainer.widthProperty().addListener((obs, oldVal, newVal) -> {
            javafx.scene.shape.Rectangle clip = new javafx.scene.shape.Rectangle(
                newVal.doubleValue(), cropperContainer.getHeight()
            );
            cropperContainer.setClip(clip);
        });
        
        cropperContainer.heightProperty().addListener((obs, oldVal, newVal) -> {
            javafx.scene.shape.Rectangle clip = new javafx.scene.shape.Rectangle(
                cropperContainer.getWidth(), newVal.doubleValue()
            );
            cropperContainer.setClip(clip);
        });
    }
    
    /**
     * 设置原始图像
     * @param image 要裁剪的图像
     */
    public void setImage(Image image) {
        this.originalImage = image;
        
        if (image == null) {
            System.err.println("错误: 尝试设置空图像");
            return;
        }
        
        // 打印图像信息
        System.out.println("设置原始图像: 尺寸=(" + image.getWidth() + "x" + image.getHeight() + ")");
        
        // 设置初始图像
        sourceImageView.setImage(image);
        
        // 重置参数
        imageOffsetX = 0;
        imageOffsetY = 0;
        currentScale.set(1.0);
        
        // 计算初始显示
        centerImage();
        updateImageScale();
        
        // 图像加载完成后更新预览
        Platform.runLater(() -> {
            updatePreview();
            System.out.println("图像初始化预览完成");
        });
    }
    
    /**
     * 处理鼠标按下事件
     */
    private void handleMousePressed(MouseEvent event) {
        startDragX = event.getX();
        startDragY = event.getY();
        event.consume();
    }
    
    /**
     * 处理鼠标拖动事件
     */
    private void handleMouseDragged(MouseEvent event) {
        double dragX = event.getX() - startDragX;
        double dragY = event.getY() - startDragY;
        
        // 调整图像位置
        imageOffsetX += dragX;
        imageOffsetY += dragY;
        
        // 更新开始拖动位置
        startDragX = event.getX();
        startDragY = event.getY();
        
        // 限制图像不会拖出裁剪圆太远
        double circleRadius = cropCircle.getRadius();
        double imageWidth = sourceImageView.getBoundsInLocal().getWidth();
        double imageHeight = sourceImageView.getBoundsInLocal().getHeight();
        
        // 计算边界，允许适当的拖动余量
        double maxOffsetX = imageWidth / 2 + circleRadius;
        double maxOffsetY = imageHeight / 2 + circleRadius;
        
        // 限制拖动范围
        imageOffsetX = Math.min(Math.max(imageOffsetX, -maxOffsetX), maxOffsetX);
        imageOffsetY = Math.min(Math.max(imageOffsetY, -maxOffsetY), maxOffsetY);
        
        // 应用变换
        sourceImageView.setTranslateX(imageOffsetX);
        sourceImageView.setTranslateY(imageOffsetY);
        
        // 更新预览
        updatePreview();
        
        event.consume();
    }
    
    /**
     * 处理鼠标滚轮事件
     */
    private void handleScroll(ScrollEvent event) {
        double deltaY = event.getDeltaY();
        double scale = currentScale.get();
        
        // 向上滚动增加缩放，向下滚动减少缩放
        if (deltaY > 0) {
            scale += SCALE_DELTA;
        } else {
            scale -= SCALE_DELTA;
        }
        
        // 确保缩放在有效范围内
        scale = Math.min(Math.max(scale, MIN_SCALE), MAX_SCALE);
        
        // 更新缩放值，会触发监听器更新图像
        currentScale.set(scale);
        
        event.consume();
    }
    
    /**
     * 更新图像缩放 - 只缩放ImageView而不是整个容器
     */
    private void updateImageScale() {
        double scale = currentScale.get();
        
        if (originalImage == null) {
            System.err.println("错误: 原始图像为空，无法缩放");
            return;
        }
        
        // 原始图像尺寸
        double originalWidth = originalImage.getWidth();
        double originalHeight = originalImage.getHeight();
        
        // 计算裁剪区域的直径（固定值）
        double cropDiameter = cropCircle.getRadius() * 2;
        
        // 计算初始缩放比例（使图像能够填充裁剪圆）
        double initialScale;
        
        // 比较宽高比，确保图像至少填充整个裁剪圆
        double imageRatio = originalWidth / originalHeight;
        double cropRatio = 1.0; // 圆形，宽高比为1
        
        if (imageRatio > cropRatio) {
            // 图像较宽，用高度作为基准
            initialScale = cropDiameter / originalHeight;
        } else {
            // 图像较高，用宽度作为基准
            initialScale = cropDiameter / originalWidth;
        }
        
        // 应用用户的缩放比例
        double finalWidth = originalWidth * initialScale * scale;
        double finalHeight = originalHeight * initialScale * scale;
        
        // 更新图像尺寸
        sourceImageView.setFitWidth(finalWidth);
        sourceImageView.setFitHeight(finalHeight);
        
        // 确保维持宽高比
        sourceImageView.setPreserveRatio(true);
        
        // 打印调试信息
        System.out.println("缩放图像: 原始尺寸=(" + originalWidth + "x" + originalHeight + 
                         "), 缩放后=(" + finalWidth + "x" + finalHeight + 
                         "), 初始比例=" + initialScale +
                         ", 用户比例=" + scale);
    }
    
    /**
     * 居中图像
     */
    private void centerImage() {
        imageOffsetX = 0;
        imageOffsetY = 0;
        sourceImageView.setTranslateX(imageOffsetX);
        sourceImageView.setTranslateY(imageOffsetY);
    }
    
    /**
     * 重置缩放和位置
     */
    @FXML
    private void resetZoomAndPosition() {
        currentScale.set(1.0);
        centerImage();
        updateImageScale();
        updatePreview();
    }
    
    /**
     * 更新预览 - 确保只捕获裁剪区域的内容
     */
    private void updatePreview() {
        try {
            // 计算裁剪圆的边界
            double circleDiameter = cropCircle.getRadius() * 2;
            double circleRadius = cropCircle.getRadius();
            
            // 获取中心坐标
            double centerX = cropperContainer.getWidth() / 2;
            double centerY = cropperContainer.getHeight() / 2;
            
            // 创建只针对圆形区域的裁剪参数
            SnapshotParameters parameters = new SnapshotParameters();
            parameters.setFill(Color.TRANSPARENT);
            
            // 精确定位视口，确保只捕获圆形区域
            parameters.setViewport(new javafx.geometry.Rectangle2D(
                centerX - circleRadius,
                centerY - circleRadius,
                circleDiameter, circleDiameter));
            
            // 创建裁剪后的图像
            WritableImage croppedImage = new WritableImage((int)circleDiameter, (int)circleDiameter);
            
            // 对裁剪区域进行快照
            cropperContainer.snapshot(parameters, croppedImage);
            
            // 为预览图像应用圆形裁剪
            previewImageView.setImage(croppedImage);
            
            // 应用圆形裁剪，以保证预览是圆形的
            Circle previewClip = new Circle(
                previewImageView.getFitWidth() / 2,
                previewImageView.getFitHeight() / 2,
                previewImageView.getFitWidth() / 2);
            previewImageView.setClip(previewClip);
            
            // 打印调试信息
            System.out.println("更新预览: 中心=(" + centerX + "," + centerY + "), 半径=" + circleRadius);
            
        } catch (Exception e) {
            System.err.println("更新预览时出错: " + e.getMessage());
            e.printStackTrace();
        }
    }
    
    /**
     * 获取裁剪后的图像
     * @return 裁剪后的图像
     */
    public Image getCroppedImage() {
        try {
            // 使用与预览相同的方法裁剪图像，确保一致性
            
            // 计算裁剪圆的边界
            double circleDiameter = cropCircle.getRadius() * 2;
            double circleRadius = cropCircle.getRadius();
            
            // 创建只针对圆形区域的裁剪参数
            SnapshotParameters parameters = new SnapshotParameters();
            parameters.setFill(Color.TRANSPARENT);
            
            // 设置与预览相同的视口
            parameters.setViewport(new javafx.geometry.Rectangle2D(
                cropperContainer.getWidth() / 2 - circleRadius,
                cropperContainer.getHeight() / 2 - circleRadius,
                circleDiameter, circleDiameter));
            
            // 创建裁剪后的图像
            WritableImage croppedImage = new WritableImage((int)circleDiameter, (int)circleDiameter);
            
            // 对裁剪区域进行快照
            cropperContainer.snapshot(parameters, croppedImage);
            
            // 确保返回的图像与预览完全相同
            System.out.println("获取最终裁剪图像: 直径=" + circleDiameter);
            
            return croppedImage;
        } catch (Exception e) {
            System.err.println("获取裁剪图像时出错: " + e.getMessage());
            e.printStackTrace();
            
            // 发生错误时尝试返回预览图像
            return previewImageView.getImage();
        }
    }
    
    /**
     * 获取裁剪后的图像文件
     * @return 裁剪后的图像文件
     * @throws IOException 如果保存失败
     */
    public File getCroppedImageFile() throws IOException {
        if (tempCroppedFile != null) {
            tempCroppedFile.delete();
        }
        
        // 创建临时文件
        tempCroppedFile = File.createTempFile("avatar_cropped_", ".png");
        tempCroppedFile.deleteOnExit();
        
        // 获取裁剪后的图像
        Image croppedImage = getCroppedImage();
        
        // 将JavaFX图像转换为BufferedImage并保存
        saveToFile(croppedImage, tempCroppedFile);
        
        return tempCroppedFile;
    }
    
    /**
     * 将JavaFX图像保存到文件
     * @param image 图像
     * @param file 文件
     * @throws IOException 如果保存失败
     */
    private void saveToFile(Image image, File file) throws IOException {
        int width = (int) image.getWidth();
        int height = (int) image.getHeight();
        
        System.out.println("保存裁剪图像: 尺寸=(" + width + "x" + height + ")");
        
        // 创建BufferedImage，使用ARGB以支持透明度
        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        
        // 获取JavaFX图像的像素
        PixelReader pixelReader = image.getPixelReader();
        
        // 计算圆形边界
        double centerX = width / 2.0;
        double centerY = height / 2.0;
        double radius = Math.min(width, height) / 2.0;
        double radiusSquared = radius * radius;
        
        // 将像素复制到BufferedImage，同时应用圆形裁剪
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                // 计算点到圆心的距离
                double dx = x - centerX;
                double dy = y - centerY;
                double distanceSquared = dx * dx + dy * dy;
                
                if (distanceSquared <= radiusSquared) {
                    // 在圆内，保留像素
                    javafx.scene.paint.Color color = pixelReader.getColor(x, y);
                    int argb = ((int) (color.getOpacity() * 255) << 24) |
                              ((int) (color.getRed() * 255) << 16) |
                              ((int) (color.getGreen() * 255) << 8) |
                              ((int) (color.getBlue() * 255));
                    bufferedImage.setRGB(x, y, argb);
                } else {
                    // 在圆外，设置为透明
                    bufferedImage.setRGB(x, y, 0);
                }
            }
        }
        
        // 保存BufferedImage到文件
        try (FileOutputStream stream = new FileOutputStream(file)) {
            ImageIO.write(bufferedImage, "png", stream);
            stream.flush();
            System.out.println("图像已成功保存: " + file.getAbsolutePath());
        }
    }
} 